package ks.server.controllers.commands.general.table;

import ks.framework.common.Message;
import ks.framework.communicator.Communicator;
import ks.framework.interfaces.IProcessMessage;
import ks.managers.table.Table;
import ks.managers.table.TableManager;
import ks.server.ServerContext;
import ks.server.ipc.Listener;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * Server-side controller for processing request to join table.
 * <p>
 * If first user on the table, then assigned as moderator. If table is restricted
 * then moderator is told of the pending request.
 * 
 * @author Christopher Page
 * @author Jared
 */
public class JoinController implements IProcessMessage {

	/** Primary agent to whom we can communicate our messages. */
	Communicator com;
	
	public static final String tableAtt = "table";
	
	/** Default controller constructor. */
	public JoinController (Communicator com) {
		this.com = com;
	}
	
	/** 
	 * process the message
	 * 
	 * @param m
	 * @return
	 */
	public boolean process(Message m) {
		Node joinNode = m.contents();
		
		if (joinNode == null) {
			Listener.nack(m, 4, "[JoinController]: joinNode null.");
			return false;
		}
		if (!joinNode.getNodeName().equalsIgnoreCase("join")) {
			Listener.nack(m, 4, "[JoinController]: joinNode incorrect.");
			return false;
		}
		
		NamedNodeMap nnp = joinNode.getAttributes();
		
		Node tableNode = nnp.getNamedItem("table");
		
		if (tableNode == null) {
			Listener.nack(m, 4, "[JoinController]: tableNode null.");
			return false;
		}
		
		int tableNum = Integer.parseInt(tableNode.getNodeValue());
		String player = m.getOriginator();
		
		if (player == null) {
			Listener.nack(m, 4, "[JoinController]: player null.");
			return false;
		}
		
		TableManager tm = ServerContext.getTableManager();
		
		Table table = tm.getTable(tableNum);
		
		if (table == null) {
			Listener.nack(m, 4, "[JoinController]: table  at " + tableNum + " null.");
			return false;
		}
		
		if (table.isFull()) {
			Listener.nack(m, 4, "[JoinController]: table full.");
			return false;
		}
		
		boolean tableEmpty = table.isEmpty();
		
		table.addPlayer(player);
		
		StringBuilder sb = new StringBuilder("<request version='1.0' id='589a39591271844e3fbe32bbb9281ad9'>");
		sb.append("<joined table=\"" + tableNum + "\" player=\"" + player + "\" />");
		sb.append("</request>");
		
		// send request to command originator
		Document d = Message.construct(sb.toString());
		Message r = new Message(d);
		//r.setRecipient(m.getOriginator());
		r.setBroadcast();
		if (!com.distribute(r)) {
			table.removePlayer(player);
			Listener.nack(m, 4, "[JoinController]: joined req failed.");
			return false;
		}
		else {
			Message m2 = Listener.ack(m, "[JoinController]: joined req success.");
			m2.setRecipient(m.getOriginator());
			com.distribute(m2);
		}
		
		if (tableEmpty) {
			
			table.setModerator(player);
			System.out.println(table.getModerator());
			sb = new StringBuilder("<request version='1.0' id='589a39591271844e3fbe32bbb9281ad9'>");
			sb.append("<moderator table=\"" + tableNum + "\" player=\"" + player + "\" />");
			sb.append("</request>");
			
			// send request to command originator
			d = Message.construct(sb.toString());
			r = new Message(d);
			//r.setRecipient(m.getOriginator());
			r.setBroadcast();
			
			if (!com.distribute(r)) {
				table.setModerator(null);
				return false;
			}
		}
		
		sb = new StringBuilder("<request version='1.0' id='589a39591271844e3fbe32bbb9281ad9'>");
		sb.append("<table-info>");
		sb.append("<table id=\"" + tableNum + "\" open=\"true\" moderator=\"" + table.getModerator() + "\">");
		for (String player2 : table.getPlayers()) {
			if (player2 != null) {
				sb.append("<playername name=\"" + player2 + "\"/>");
			}
		}
		sb.append("</table>");
		sb.append("</table-info>");
		sb.append("</request>");
		
		d = Message.construct(sb.toString());
		r = new Message(d);
		r.setRecipient(m.getOriginator());
		
		if (!com.distribute(r)) {
			return false;
		}
		
		return true;
	}
}
